from sanic import Sanic
from sanic_cors import CORS
from sanic import Blueprint
from tortoise.contrib.sanic import register_tortoise
from werkzeug.utils import ImportStringError, find_modules, import_string

# from .http import http
# from .listener import listen

# 初始化项目
def create_app(config=None):

    # 初始化 Sanic
    app = Sanic(__name__)

    # 解决跨域
    CORS(app)

    # 注册数据库 配置
    config = register_database(app, config)

    # 设置 config配置 项
    app.config.update(config)

    # 静态资源目录
    app.static('/static', app.config['static'])

    # 注册蓝图
    try:
        # 判断是否开启多模块
        if app.config['multi_module'] == False:
            register_blueprints('app.controller', app)
        else:
            # 遍历得到配置里面的模块
            for key, value in app.config['module'].items():
                register_blueprints('app.controller.'+key, app, value)
    except ImportStringError:
        ...

    # 注册服务 监听器 请求
    # register_server(app)

    return app

# 注册数据库
def register_database(app, config):
    # 连接数据库的参数
    config['DB_ARGS'] = dict(
        host=config['DB_HOST'],
        port=config['DB_PORT'],
        user=config['DB_USER'],
        password=config['DB_PASS'],
        database=config['DB_NAME'],
        charset=config['DB_CHARTSET'],
    )

    # 数据库连接
    # register_tortoise(
    #     app,
    #     db_url="sqlite:///data.db",
    #     modules={"models": ["app.model"]},
    #     generate_schemas=True
    # )

    # 数据库连接
    config['DB_URL'] = "mysql://{user}:{password}@{host}:{port}/{database}?charset={charset}".format(**config['DB_ARGS'])

    # 注册 tortoise 数据库 连接
    register_tortoise(
        app,
        db_url=config['DB_URL'],
        modules={"models": ['app.model']},
        generate_schemas=False
    )

    return config

# 注册蓝图
def register_blueprints(root, app, prefix='/'):
    # 遍历模块列表
    for name in find_modules(root, recursive=True):
        mod = import_string(name)

        # 判断是否有 bp
        if hasattr(mod, 'bp'):
            # 注册路由
            route = Blueprint.group(mod.bp, url_prefix=prefix)
            app.blueprint(route)

# 注册服务
# def register_server(app):
#
#     # 判断是否开启 注册监听器
#     if app.config['listen'] == True:
#         # 注册监听器
#         app.register_listener(listen.before_server_start, 'before_server_start')
#         app.register_listener(listen.before_server_stop, 'before_server_stop')
#         app.register_listener(listen.after_server_start, 'after_server_start')
#         app.register_listener(listen.after_server_stop, 'after_server_stop')
#
#     # 请求
#     @app.on_request
#     async def request(request):
#         http.request(request)
#
#     # 响应
#     @app.on_response
#     async def response(request, response):
#         http.response(request, response)